home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / clients / viewres / viewres.c < prev    next >
Text File  |  1994-08-12  |  37KB  |  1,231 lines

  1. /*
  2.  * $XConsortium: viewres.c,v 1.72 91/07/23 21:04:33 converse Exp $
  3.  *
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted, provided
  8.  * that the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising
  11.  * or publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Jim Fulton, MIT X Consortium
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <X11/StringDefs.h>
  28. #ifdef MSDOS
  29. #include "X11/IntrinsP.h"      /* QDK 05/11/1994  3:05pm. */
  30. #include <X11/Xaw/Cardinal.h>
  31. #else
  32. #include "X11/IntrinsicP.h"
  33. #include <X11/Xaw/Cardinals.h>
  34. #endif
  35. #include <X11/Xaw/Box.h>
  36. #include <X11/Xaw/Form.h>
  37. #include <X11/Xaw/Command.h>
  38. #ifdef MSDOS
  39. #include <X11/Xaw/MenuButt.h>
  40. #include <X11/Xaw/SimpleMe.h>
  41. #else
  42. #include <X11/Xaw/MenuButton.h>
  43. #include <X11/Xaw/SimpleMenu.h>
  44. #endif
  45.  
  46. #include <X11/Xaw/Sme.h>
  47. #include <X11/Xaw/SmeBSB.h>
  48. #include <X11/Xaw/SmeLine.h>
  49. #include <X11/Xaw/Paned.h>
  50. #include <X11/Xaw/Porthole.h>
  51. #include <X11/Xaw/Toggle.h>
  52. #include <X11/Xaw/Text.h>
  53. #include <X11/Xaw/List.h>
  54. #ifdef MSDOS
  55. #include <X11/Xaw/Scrollba.h>
  56. #else
  57. #include <X11/Xaw/Scrollbar.h>
  58. #endif
  59. #include <X11/Xaw/Panner.h>
  60. #include <X11/Xaw/Tree.h>
  61. #include <X11/Xmu/Converters.h>
  62. #include <X11/Xmu/CharSet.h>
  63. #include <X11/Xmu/WidgetNode.h>
  64. #include <X11/Xaw/AllWidgets.h>
  65.  
  66. extern char *malloc(), *calloc();
  67.  
  68. #define widget_list XawWidgetArray  /* or motif or ol or ... */
  69. #define nwidgets XawWidgetCount
  70.  
  71. typedef struct {
  72.     char **resource_labels;        /* names of res added by widget */
  73.     Cardinal nnewresources;        /* number res added by widget */
  74.     Cardinal nnewconstraints;        /* number res added by widget */
  75.     Cardinal nnew;            /* number new */
  76.     Widget instance;            /* Label widget in box in tree */
  77.     Widget resource_lw;            /* List widget showing resources */
  78.     int selection_index;        /* -1 or index into selection_list */
  79. } ViewresData;
  80.  
  81. #define VData(node) ((ViewresData *) (node)->data)
  82.  
  83.  
  84. #define IsShowing(node) (VData(node)->resource_lw && \
  85.              XtIsManaged(VData(node)->resource_lw))
  86.  
  87.  
  88. struct {
  89.     int n_elements;
  90.     int max_elements;
  91.     XmuWidgetNode **elements;
  92. } selected_list = { 0, 0, (XmuWidgetNode **) NULL };
  93.  
  94. #define INSERT_NODE(node,i) \
  95.   selected_list.elements[VData(node)->selection_index = (i)] = (node)
  96.  
  97. #define REMOVE_NODE(node) \
  98.   selected_list.elements[VData(node)->selection_index] = \
  99.   (XmuWidgetNode *) NULL; VData(node)->selection_index = (-1)
  100.  
  101. char *ProgramName;
  102. static int NumberShowing = 0;
  103.  
  104. static Arg sensitiveargs[2] = {{ XtNsensitive, (XtArgVal) FALSE },
  105.                    { XtNsensitive, (XtArgVal) TRUE }};
  106.  
  107. static char *help_message[] = {
  108.     "-top name        object to be top of tree",
  109.     "-variable        show variable name instead of class name",
  110.     "-vertical        list the tree vertically",
  111.     (char *) NULL
  112. };
  113.  
  114. static XrmOptionDescRec Options[] = {
  115.     { "-top", "*topObject", XrmoptionSepArg, (XPointer) NULL },
  116.     { "-variable", "*showVariable", XrmoptionNoArg, (XPointer) "on" },
  117.     { "-vertical", "*Tree.Gravity", XrmoptionNoArg, (XPointer) "north" }
  118. };
  119.  
  120.  
  121. typedef struct {
  122.     char *top_object;
  123.     Boolean show_variable;
  124. } OptionsRec;
  125.  
  126. static OptionsRec options;
  127.  
  128. #define Offset(field) XtOffsetOf(OptionsRec, field)
  129.  
  130. static XtResource Resources[] = {
  131.     { "topObject", "TopObject", XtRString, sizeof(char *),
  132.     Offset(top_object), XtRString, (XtPointer) "object" },
  133.     { "showVariable", "ShowVariable", XtRBoolean, sizeof(Boolean),
  134.     Offset(show_variable), XtRImmediate, (XtPointer) FALSE },
  135. };
  136.  
  137. #undef Offset
  138.  
  139. static char *fallback_resources[] = {
  140.     "*allowShellResize: true",
  141.     "*Porthole.top: ChainTop",
  142.     "*Porthole.left: ChainLeft",
  143.     "*Porthole.bottom: ChainBottom",
  144.     "*Porthole.right:  ChainRight",
  145.     "*Porthole.resizable: on",
  146.     "*Panner.top: ChainTop",
  147.     "*Panner.left: ChainLeft",
  148.     "*Panner.bottom: ChainTop",
  149.     "*Panner.right:  ChainLeft",
  150.     "*Panner.resizable: on",
  151.     "*Tree*ShapeStyle: rectangle",
  152.     "*Tree*Toggle*BorderWidth: 0",
  153.     "*Porthole*Box.BorderWidth: 0",
  154.     "*Porthole*Box.HSpace: 0",
  155.     "*Porthole*Box.VSpace: 0",
  156.     "*Paned*allowResize: true",
  157.     "*buttonbox.quit.Translations:  #override \\n <Btn1Down>,<Btn1Up>: Quit() unset()",
  158.     "*Toggle.Translations: #augment \\n <Btn2Down>,<Btn2Up>: set() notify() Resources(toggle)",
  159.     (char *) NULL
  160. };
  161.  
  162. static void ActionQuit(), ActionSetLableType(), ActionSetOrientation();
  163. static void ActionSelect(), ActionResources();
  164. static void set_labeltype_menu(), set_orientation_menu();
  165. static void build_tree(), set_node_labels();
  166.  
  167. static XtActionsRec viewres_actions[] = {
  168.     { "Quit", ActionQuit },
  169.     { "SetLabelType", ActionSetLableType },
  170.     { "SetOrientation", ActionSetOrientation },
  171.     { "Select", ActionSelect },
  172.     { "Resources", ActionResources },
  173. };
  174.  
  175. static Atom wm_delete_window;
  176.  
  177. #define BOOL_OFF 0
  178. #define BOOL_ON 1
  179. #define BOOL_TOGGLE 2
  180.  
  181. #define VIEW_HORIZONTAL 0
  182. #define VIEW_VERTICAL 1
  183. #define VIEW_VARIABLES 2
  184. #define VIEW_CLASSES 3
  185. #define VIEW_SHOW_RESOURCES 4
  186. #define VIEW_HIDE_RESOURCES 5
  187. #define VIEW_number 6
  188.  
  189. #define SELECT_NOTHING 0
  190. #define SELECT_ALL 1
  191. #define SELECT_INVERT 2
  192. #define SELECT_PARENT 3
  193. #define SELECT_ANCESTORS 4
  194. #define SELECT_CHILDREN 5
  195. #define SELECT_DESCENDANTS 6
  196. #define SELECT_HAS_RESOURCES 7
  197. #define SELECT_SHOWN_RESOURCES 8
  198. #define SELECT_number 9
  199.  
  200. static struct _nametable {
  201.     char *name;
  202.     int value;
  203. } select_nametable[] = {
  204.     { "nothing", SELECT_NOTHING },
  205.     { "all", SELECT_ALL },
  206.     { "invert", SELECT_INVERT },
  207.     { "parent", SELECT_PARENT },
  208.     { "ancestors", SELECT_ANCESTORS },
  209.     { "children", SELECT_CHILDREN },
  210.     { "descendants", SELECT_DESCENDANTS },
  211.     { "resources", SELECT_HAS_RESOURCES },
  212.     { "shown", SELECT_SHOWN_RESOURCES },
  213. }, boolean_nametable[] = {
  214.     { "off", BOOL_OFF },
  215.     { "false", BOOL_OFF },
  216.     { "no", BOOL_OFF },
  217.     { "on", BOOL_ON },
  218.     { "true", BOOL_ON },
  219.     { "yes", BOOL_ON },
  220.     { "toggle", BOOL_TOGGLE },
  221. };
  222.  
  223. static Widget treeWidget;
  224. static Widget quitButton, viewButton, viewMenu, selectButton, selectMenu;
  225. static Widget view_widgets[VIEW_number];
  226. static Widget select_widgets[SELECT_number];
  227. static XmuWidgetNode *topnode;
  228.  
  229. static Arg false_args[1] = {{ XtNstate, (XtArgVal) FALSE }};
  230. static Arg true_args[1] = {{ XtNstate, (XtArgVal) TRUE }};
  231.  
  232.  
  233. /*
  234.  * routines
  235.  */
  236. static void usage ()
  237. {
  238.     char **cpp;
  239.     fprintf (stderr, "usage:  %s [-options...]\n", ProgramName);
  240.     fprintf(stderr, "\nwhere options include:\n");
  241.     for (cpp = help_message; *cpp; cpp++) {
  242.     fprintf (stderr, "    %s\n", *cpp);
  243.     }
  244.     fprintf(stderr, "\n");
  245.     exit (1);
  246. }
  247.  
  248.  
  249. static XmuWidgetNode *widget_to_node (gw)
  250.     register Widget gw;
  251. {
  252.     register XmuWidgetNode *node;
  253.     register int i;
  254.  
  255.     if (XtIsSubclass (gw, toggleWidgetClass)) {
  256.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  257.         if (VData(node)->instance == gw) return node;
  258.     }
  259.     } else if (XtIsSubclass (gw, listWidgetClass)) {
  260.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  261.         if (VData(node)->resource_lw == gw) return node;
  262.     }
  263.     }
  264.     return (XmuWidgetNode *) NULL;
  265. }
  266.  
  267.  
  268. static void initialize_widgetnode_list (listp, sizep, n)
  269.     XmuWidgetNode ***listp;
  270.     int *sizep;
  271.     int n;
  272. {
  273.     register int i;
  274.     register XmuWidgetNode **l;
  275.  
  276.     if (!*listp) {
  277.         *listp = (XmuWidgetNode **)
  278.       XtCalloc ((unsigned int) n, (unsigned int)sizeof(XmuWidgetNode **));
  279.         *sizep = ((*listp) ? n : 0);
  280.         return;
  281.     }
  282.     if (n > *sizep) {
  283.         *listp = (XmuWidgetNode **) XtRealloc ((char *) *listp,
  284.                            (unsigned int) 
  285.                            (n * sizeof(XmuWidgetNode **)));
  286.     if (!*listp) {
  287.         *sizep = 0;
  288.         return;
  289.     }
  290.     for (i = *sizep, l = (*listp) + i; i < n; i++, l++) *l =
  291.       (XmuWidgetNode *) NULL;
  292.     *sizep = n;
  293.     }
  294.     return;
  295. }
  296.  
  297.  
  298. static Boolean set_resource_labels (node)
  299.     XmuWidgetNode *node;
  300. {
  301.     int i;
  302.     char **cur;
  303.     XtResourceList res;
  304.     XmuWidgetNode **wn;
  305.     ViewresData *d = VData(node);
  306.  
  307.     if (!d->resource_labels) {
  308.     d->resource_labels =
  309.       (char **) calloc ((unsigned) d->nnew * 3,
  310.                 (unsigned) sizeof (char *));
  311.     if (!d->resource_labels) return FALSE;
  312.     }
  313.  
  314.     cur = d->resource_labels;
  315.     res = node->resources;
  316.     wn = node->resourcewn;
  317.     for (i = 0; i < node->nresources; i++, res++, wn++) {
  318.     if (*wn == node) {        /* should match nnew */
  319.         *cur++ = res->resource_name;
  320.         *cur++ = res->resource_class;
  321.         *cur++ = res->resource_type;
  322.     }
  323.     }
  324.     if (d->nnewconstraints > 0) {
  325.     char *s;
  326.  
  327.     *cur++ = s = "";
  328.     *cur++ = s;
  329.     *cur++ = s;
  330.     }
  331.     res = node->constraints;
  332.     wn = node->constraintwn;
  333.     for (i = 0; i < node->nconstraints; i++, res++, wn++) {
  334.     if (*wn == node) {        /* should match nnew */
  335.         *cur++ = res->resource_name;
  336.         *cur++ = res->resource_class;
  337.         *cur++ = res->resource_type;
  338.     }
  339.     }
  340.     return TRUE;
  341. }
  342.  
  343.  
  344. static ViewresData *create_viewres_data (node)
  345.     XmuWidgetNode *node;
  346. {
  347.     register ViewresData *d =
  348.       (ViewresData *) malloc ((unsigned) sizeof(ViewresData));
  349.  
  350.     if (d) {
  351.     d->resource_labels = (char **) NULL;
  352.     d->nnewresources = XmuWnCountOwnedResources (node, node, False);
  353.     d->nnewconstraints = XmuWnCountOwnedResources (node, node, True);
  354.     d->nnew = (d->nnewresources + (d->nnewconstraints 
  355.                        ? d->nnewconstraints + 1 : 0));
  356.     d->instance = (Widget) NULL;
  357.     d->resource_lw = (Widget) NULL;
  358.     d->selection_index = -1;
  359.     }
  360.     return d;
  361. }
  362.  
  363. static int copydown (start)
  364.     register int start;
  365. {
  366.     register XmuWidgetNode **src = &selected_list.elements[start];
  367.     register XmuWidgetNode **dst = src;
  368.     register int cur;
  369.  
  370.     for (cur = start; start < selected_list.n_elements; start++, src++) {
  371.     if (*src) {
  372.         VData((*src))->selection_index = cur++;
  373.         *dst++ = *src;
  374.     }
  375.     }
  376.     return (start - cur);
  377. }
  378.  
  379.  
  380. static void add_to_selected_list (node, updatewidget)
  381.     XmuWidgetNode *node;
  382.     Boolean updatewidget;
  383. {
  384.     ViewresData *d = VData(node);
  385.     if (!d->instance || d->selection_index >= 0) return;
  386.  
  387.     if (selected_list.n_elements >= selected_list.max_elements) {
  388.     initialize_widgetnode_list (&selected_list.elements,
  389.                     &selected_list.max_elements, 
  390.                     (selected_list.max_elements * 3) / 2);
  391.     }
  392.     INSERT_NODE (node, selected_list.n_elements);
  393.     selected_list.n_elements++;
  394.  
  395.     if (updatewidget) XtSetValues (d->instance, true_args, ONE);
  396. }
  397.  
  398. static Boolean remove_from_selected_list (node, updatewidget)
  399.     XmuWidgetNode *node;
  400.     Boolean updatewidget;
  401. {
  402.     int i, skips;
  403.     ViewresData *d = VData(node);
  404.  
  405.     if ((i = d->selection_index) < 0) return FALSE;
  406.  
  407.     REMOVE_NODE (node);
  408.  
  409.     /* copy down */
  410.     if (selected_list.n_elements > 1) {
  411.     skips = copydown (i);
  412.     } else {
  413.     skips = 1;
  414.     }
  415.     selected_list.n_elements -= skips;
  416.  
  417.     if (updatewidget) XtSetValues (d->instance, false_args, ONE);
  418.     return TRUE;
  419. }
  420.  
  421. static void remove_nodes_from_selected_list (start, count, updatewidget)
  422.     int start, count;
  423.     Boolean updatewidget;
  424. {
  425.     int i;
  426.  
  427.     for (i = 0; i < count; i++) {
  428.     register XmuWidgetNode *p = selected_list.elements[start+i];
  429.     ViewresData *d = VData(p);
  430.     REMOVE_NODE (p);
  431.     if (updatewidget) XtSetValues (d->instance, false_args, ONE);
  432.     }
  433.     selected_list.n_elements -= copydown (start);
  434. }
  435.         
  436. static void add_subtree_to_selected_list (node, updatewidget)
  437.     XmuWidgetNode *node;
  438.     Boolean updatewidget;
  439. {
  440.     if (!node) return;
  441.  
  442.     add_to_selected_list (node, updatewidget);
  443.     for (node = node->children; node; node = node->siblings) {
  444.     add_subtree_to_selected_list (node, updatewidget);
  445.     }
  446. }
  447.  
  448.  
  449. /* ARGSUSED */
  450. static void variable_labeltype_callback (gw, closure, data)
  451.     Widget gw;
  452.     XtPointer closure;            /* TRUE or FALSE */
  453.     XtPointer data;
  454. {
  455.     set_labeltype_menu ((Boolean) closure, True);
  456. }
  457.  
  458. /* ARGSUSED */
  459. static void gravity_callback (gw, closure, data)
  460.     Widget gw;
  461.     XtPointer closure;            /* TRUE or FALSE */
  462.     XtPointer data;
  463. {
  464.     set_orientation_menu ((XtGravity) closure, True);
  465. }
  466.  
  467.  
  468. static Boolean create_resource_lw (node)
  469.     XmuWidgetNode *node;
  470. {
  471.     Arg args[4];
  472.     Cardinal n;
  473.     ViewresData *d = VData(node);
  474.  
  475.     if (d->nnew == 0) return FALSE;
  476.  
  477.     if (!d->resource_labels &&
  478.     !set_resource_labels (node)) return FALSE;
  479.  
  480.     n = 0;
  481.     XtSetArg (args[n], XtNnumberStrings, 3 * d->nnew); n++;
  482.     XtSetArg (args[n], XtNlist, d->resource_labels); n++;
  483.     XtSetArg (args[n], XtNdefaultColumns, 3); n++;
  484.     XtSetArg (args[n], XtNforceColumns, TRUE); n++;
  485.     d->resource_lw = XtCreateManagedWidget (node->label, listWidgetClass,
  486.                         XtParent(d->instance),
  487.                         args, n);
  488.     XtRealizeWidget (d->resource_lw);
  489.     return TRUE;
  490. }
  491.  
  492. static void update_selection_items ()
  493. {
  494.     register int i;
  495.     static Arg args[1] = {{ XtNsensitive, (XtArgVal) FALSE }};
  496.     Boolean show = FALSE, hide = FALSE, ancestors = FALSE;
  497.     Boolean descendants = FALSE;
  498.  
  499.     for (i = 0; i < selected_list.n_elements; i++) {
  500.     XmuWidgetNode *node = selected_list.elements[i];
  501.     ViewresData *d = VData(node);
  502.  
  503.     /*
  504.      * If node has any new resources then may be shown (if not
  505.      * already being shown).  If node has widget and is managed,
  506.      * then may be hidden.
  507.      */
  508.     if (d->nnew > 0) {
  509.         if (IsShowing(node)) {
  510.         hide = TRUE;
  511.         } else {
  512.         show = TRUE;
  513.         }
  514.     }
  515.     if (node != topnode) ancestors = TRUE;
  516.     if (node->children) descendants = TRUE;
  517.     }
  518.         
  519.     args[0].value = (XtArgVal) show;
  520.     XtSetValues (view_widgets[VIEW_SHOW_RESOURCES], args, ONE);
  521.     args[0].value = (XtArgVal) hide;
  522.     XtSetValues (view_widgets[VIEW_HIDE_RESOURCES], args, ONE);
  523.     args[0].value = (XtArgVal) (selected_list.n_elements > 0 ? TRUE : FALSE);
  524.     XtSetValues (select_widgets[SELECT_NOTHING], args, ONE);
  525.     args[0].value = (XtArgVal) ancestors;
  526.     XtSetValues (select_widgets[SELECT_PARENT], args, ONE);
  527.     XtSetValues (select_widgets[SELECT_ANCESTORS], args, ONE);
  528.     args[0].value = (XtArgVal) descendants;
  529.     XtSetValues (select_widgets[SELECT_CHILDREN], args, ONE);
  530.     XtSetValues (select_widgets[SELECT_DESCENDANTS], args, ONE);
  531.     args[0].value = (XtArgVal) ((Boolean) (NumberShowing > 0));
  532.     XtSetValues (select_widgets[SELECT_SHOWN_RESOURCES], args, ONE);
  533. }
  534.  
  535.  
  536. static void do_resources (node, op, updatewidget)
  537.     XmuWidgetNode *node;
  538.     Boolean op;
  539.     Boolean updatewidget;
  540. {
  541.     ViewresData *d = VData(node);
  542.     if (op == BOOL_TOGGLE) op = (IsShowing(node) ? BOOL_OFF : BOOL_ON);
  543.  
  544.     if (op == BOOL_ON) {
  545.     if (d->resource_lw) {        /* if already created */
  546.         if (!XtIsManaged(d->resource_lw)) {
  547.         NumberShowing++;
  548.         XtManageChild (d->resource_lw);
  549.         }                /* else ignore it */
  550.     } else if (create_resource_lw (node))    /* create it */
  551.       NumberShowing++;
  552.     } else if (d->resource_lw) {        /* if already created */
  553.     if (XtIsManaged (d->resource_lw)) {
  554.         NumberShowing--;
  555.         XtUnmanageChild (d->resource_lw);
  556.         XawListUnhighlight (d->resource_lw);
  557.         if (updatewidget) remove_from_selected_list (node, TRUE);
  558.     }                /* else ignore it */
  559.     }
  560. }
  561.  
  562.  
  563.  
  564. /* ARGSUSED */
  565. static void show_resources_callback (gw, closure, data)
  566.     Widget gw;                /* menu or toggle button */
  567.     XtPointer closure;            /* BOOL_OFF, BOOL_ON, BOOL_TOGGLE */
  568.     XtPointer data;            /* undefined */
  569. {
  570.     int op = (int) closure;
  571.     XmuWidgetNode *node = widget_to_node (gw);
  572.  
  573.     if (node) {
  574.     XUnmapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  575.     do_resources (node, op, TRUE);
  576.     } else if (selected_list.n_elements <= 0) {
  577.     return;
  578.     } else {
  579.     int i;
  580.  
  581.     XUnmapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  582.     for (i = 0; i < selected_list.n_elements; i++) {
  583.         do_resources (selected_list.elements[i], op, FALSE);
  584.     }
  585.     }
  586.     XawTreeForceLayout (treeWidget);
  587.     XMapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  588.     update_selection_items ();
  589. }
  590.  
  591.  
  592. /* ARGSUSED */
  593. static void select_callback (gw, closure, data)
  594.     Widget gw;                /* entry widget */
  595.     XtPointer closure;            /* TRUE or FALSE */
  596.     XtPointer data;            /* undefined */
  597. {
  598.     register int i;
  599.     int nselected = selected_list.n_elements;
  600.     XmuWidgetNode *node;
  601.  
  602.     switch ((int) closure) {
  603.       case SELECT_NOTHING:        /* clear selection_list */
  604.     remove_nodes_from_selected_list (0, nselected, True);
  605.     break;
  606.  
  607.       case SELECT_ALL:            /* put everything on selection_list */
  608.     add_subtree_to_selected_list (topnode, TRUE);
  609.     break;
  610.  
  611.       case SELECT_INVERT:        /* toggle selection state */
  612.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  613.         ViewresData *d = VData(node);
  614.         if (d->selection_index < 0) add_to_selected_list (node, TRUE);
  615.     }
  616.     remove_nodes_from_selected_list (0, nselected, True);
  617.     break;
  618.  
  619.  
  620.       case SELECT_PARENT:        /* choose immediate parent */
  621.     node = widget_to_node (gw);
  622.     if (node) {
  623.         if (node->superclass)
  624.           add_to_selected_list (node->superclass, TRUE);
  625.     } else {
  626.         for (i = 0; i < nselected; i++) {
  627.         XmuWidgetNode *node = selected_list.elements[i];
  628.         if (node->superclass)
  629.           add_to_selected_list (node->superclass, TRUE);
  630.         }
  631.     }
  632.     break;
  633.  
  634.       case SELECT_ANCESTORS:        /* chain up adding to selection_list */
  635.     node = widget_to_node (gw);
  636.     if (node) {
  637.         do {
  638.         add_to_selected_list (node, TRUE);
  639.         } while (node = node->superclass);
  640.     } else {
  641.         for (i = 0; i < nselected; i++) {
  642.         XmuWidgetNode *parent = selected_list.elements[i];
  643.  
  644.         /*
  645.          * chain up the tree, but stop if we get to nodes that
  646.          * are already in the selected list.
  647.          */
  648.         while (parent = parent->superclass) {  /* do ancestors */
  649.             if (VData(parent)->selection_index >= 0) break;
  650.             add_to_selected_list (parent, TRUE);
  651.         }
  652.         }
  653.     }
  654.     break;
  655.  
  656.       case SELECT_CHILDREN:        /* all direct sub nodes */
  657.     node = widget_to_node (gw);
  658.     if (node) {
  659.         add_to_selected_list (node, TRUE);
  660.         for (node = node->children; node; node = node->siblings) {
  661.         add_to_selected_list (node, TRUE);
  662.         }
  663.     } else {
  664.         for (i = 0; i < nselected; i++) {
  665.         XmuWidgetNode *node = selected_list.elements[i];
  666.  
  667.         add_to_selected_list (node, TRUE);
  668.         for (node = node->children; node; node = node->siblings) {
  669.             add_to_selected_list (node, TRUE);
  670.         }
  671.         }
  672.     }
  673.     break;
  674.  
  675.       case SELECT_DESCENDANTS:        /* all sub nodes */
  676.     node = widget_to_node (gw);
  677.     if (node) {
  678.         add_subtree_to_selected_list (node, TRUE);
  679.     } else {
  680.         for (i = 0; i < nselected; i++) {
  681.         XmuWidgetNode *parent = selected_list.elements[i];
  682.  
  683.         add_subtree_to_selected_list (parent, TRUE);
  684.         }
  685.     }
  686.     break;
  687.  
  688.       case SELECT_HAS_RESOURCES:    /* put all w/ rescnt > 0 on sel_list */
  689.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  690.         if (VData(node)->nnew > 0)
  691.           add_to_selected_list (node, TRUE);
  692.     }
  693.     break;
  694.  
  695.       case SELECT_SHOWN_RESOURCES:
  696.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  697.         if (IsShowing(node)) add_to_selected_list (node, TRUE);
  698.     }
  699.     break;
  700.  
  701.       default:                /* error!!! */
  702.     XBell (XtDisplay(gw), 0);
  703.     return;
  704.     }
  705.  
  706.     update_selection_items ();
  707. }
  708.  
  709. /* ARGSUSED */
  710. static void toggle_callback (gw, closure, data)
  711.     Widget gw;
  712.     XtPointer closure;        /* XmuWidgetNode for this widget */
  713.     XtPointer data;        /* on or off */
  714. {
  715.     XmuWidgetNode *node = (XmuWidgetNode *) closure;
  716.     Boolean selected = (Boolean) data;
  717.  
  718.     if (selected) {
  719.     add_to_selected_list (node, FALSE);
  720.     } else {
  721.     (void) remove_from_selected_list (node, FALSE);
  722.     }
  723.  
  724.     update_selection_items ();
  725. }
  726.  
  727.  
  728. /*
  729.  * panner/porthole controls - called when the other changes
  730.  */
  731. /* ARGSUSED */
  732. static void panner_callback (gw, closure, data)
  733.     Widget gw;                /* panner widget */
  734.     XtPointer closure;            /* porthole widget */
  735.     XtPointer data;            /* report */
  736. {
  737.     XawPannerReport *rep = (XawPannerReport *) data;
  738.     Arg args[2];
  739.  
  740.     if (!treeWidget) return;
  741.  
  742.     XtSetArg (args[0], XtNx, -rep->slider_x);
  743.     XtSetArg (args[1], XtNy, -rep->slider_y);
  744.     XtSetValues (treeWidget, args, TWO);    /* just assume... */
  745. }
  746.  
  747. /* ARGSUSED */
  748. static void porthole_callback (gw, closure, data)
  749.     Widget gw;                /* porthole widget */
  750.     XtPointer closure;            /* panner widget */
  751.     XtPointer data;            /* report */
  752. {
  753.     Widget panner = (Widget) closure;
  754.     XawPannerReport *rep = (XawPannerReport *) data;
  755.     Arg args[6];
  756.     Cardinal n = TWO;
  757.  
  758.     XtSetArg (args[0], XtNsliderX, rep->slider_x);
  759.     XtSetArg (args[1], XtNsliderY, rep->slider_y);
  760.     if (rep->changed != (XawPRSliderX | XawPRSliderY)) {
  761.     XtSetArg (args[2], XtNsliderWidth, rep->slider_width);
  762.     XtSetArg (args[3], XtNsliderHeight, rep->slider_height);
  763.     XtSetArg (args[4], XtNcanvasWidth, rep->canvas_width);
  764.     XtSetArg (args[5], XtNcanvasHeight, rep->canvas_height);
  765.     n = SIX;
  766.     }
  767.     XtSetValues (panner, args, n);
  768. }
  769.  
  770.  
  771.  
  772. static void build_tree (node, tree, super)
  773.     XmuWidgetNode *node;
  774.     Widget tree;
  775.     Widget super;
  776. {
  777.     ViewresData *d = VData (node);
  778.     Widget box, w;            /* widget for this Class */
  779.     XmuWidgetNode *child;            /* iterator over children */
  780.     Arg args[3];            /* need to set super node */
  781.     Cardinal n;                /* count of args */
  782.     static XtCallbackRec callback_rec[2] = {{ toggle_callback, NULL },
  783.                          { NULL, NULL }};
  784.  
  785.  
  786.     n = 0;
  787.     XtSetArg (args[n], XtNtreeParent, super); n++;
  788.     box = XtCreateManagedWidget (node->label, boxWidgetClass, tree, args, n);
  789.  
  790.     n = 0;
  791.     XtSetArg (args[n], XtNlabel, (options.show_variable ?
  792.                   node->label : XmuWnClassname(node))); n++;
  793.     XtSetArg (args[n], XtNcallback, callback_rec); n++;
  794.  
  795.     callback_rec[0].closure = (XtPointer) node;
  796.     w = XtCreateManagedWidget (node->label, toggleWidgetClass, box, args, n);
  797.     d->instance = w;
  798.  
  799.     /*
  800.      * recursively build the rest of the tree
  801.      */
  802.     for (child = node->children; child; child = child->siblings) {
  803.     build_tree (child, tree, box);
  804.     }
  805. }
  806.  
  807.  
  808. static void set_node_labels (node, depth)
  809.     XmuWidgetNode *node;
  810.     int depth;
  811. {
  812.     Arg args[1];
  813.     XmuWidgetNode *child;
  814.     ViewresData *d = VData(node);
  815.  
  816.     if (!node) return;
  817.     XtSetArg (args[0], XtNlabel, (options.show_variable ?
  818.                   node->label : XmuWnClassname(node)));
  819.     XtSetValues (d->instance, args, ONE);
  820.  
  821.     for (child = node->children; child; child = child->siblings) {
  822.     set_node_labels (child, depth + 1);
  823.     }
  824. }
  825.  
  826.  
  827. static void oneof_sensitive (choosea, a, b)
  828.     Boolean choosea;
  829.     Widget a, b;
  830. {
  831.     static Arg args[1] = { XtNsensitive, (XtArgVal) NULL };
  832.  
  833.     args[0].value = (XtArgVal) TRUE;
  834.     XtSetValues (choosea ? a : b, args, ONE);
  835.     args[0].value = (XtArgVal) FALSE;
  836.     XtSetValues (choosea ? b : a, args, ONE);
  837. }
  838.  
  839. static void set_labeltype_menu (isvar, doall)
  840.     Boolean isvar;
  841.     Boolean doall;
  842. {
  843.     options.show_variable = isvar;
  844.     oneof_sensitive (isvar, view_widgets[VIEW_CLASSES],
  845.              view_widgets[VIEW_VARIABLES]);
  846.  
  847.     if (doall) {
  848.     XUnmapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  849.     set_node_labels (topnode, 0);
  850.     XawTreeForceLayout (treeWidget);
  851.     XMapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  852.     }
  853. }
  854.  
  855. static void set_orientation_menu (grav, dosetvalues)
  856.     XtGravity grav;
  857.     Boolean dosetvalues;
  858. {
  859. #define CHOOSE(val) (sensitiveargs + (grav != (val)))
  860.     XtSetValues (view_widgets[VIEW_HORIZONTAL], CHOOSE(WestGravity), ONE);
  861.     XtSetValues (view_widgets[VIEW_VERTICAL], CHOOSE(NorthGravity), ONE);
  862. #undef CHOOSE
  863.  
  864.     if (dosetvalues) {
  865.     Arg args[1];
  866.  
  867.     XtSetArg (args[0], XtNgravity, grav);
  868.     XUnmapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  869.      XtSetValues (treeWidget, args, ONE);
  870.     XMapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  871.     }
  872. }
  873.  
  874.  
  875. /*****************************************************************************
  876.  *                                                                           *
  877.  *             viewres - visual class browser for Xt                   *
  878.  *                                                                           *
  879.  *****************************************************************************/
  880.  
  881. main (argc, argv)
  882.     int argc;
  883.     char **argv;
  884. {
  885.     Widget toplevel, pane, box, dummy, porthole, panner, form;
  886.     XtAppContext app_con;
  887.     Arg args[6];
  888.     Dimension canvasWidth, canvasHeight, sliderWidth, sliderHeight;
  889.     static XtCallbackRec callback_rec[2] = {{ NULL, NULL }, { NULL, NULL }};
  890.     XtGravity grav;
  891.     int i;
  892.  
  893.     ProgramName = argv[0];
  894.  
  895.     toplevel = XtAppInitialize (&app_con, "Viewres", 
  896.                 Options, XtNumber (Options),
  897.                 &argc, argv, fallback_resources, 
  898.                 (ArgList) NULL, ZERO);
  899.     if (argc != 1) usage ();
  900.  
  901.     initialize_widgetnode_list (&selected_list.elements,
  902.                 &selected_list.max_elements, 10);
  903.  
  904.     XtGetApplicationResources (toplevel, (XtPointer) &options,
  905.                    Resources, XtNumber(Resources), NULL, ZERO);
  906.     XmuWnInitializeNodes (widget_list, nwidgets);
  907.  
  908.     topnode = XmuWnNameToNode (widget_list, nwidgets, options.top_object);
  909.     if (!topnode) {
  910.     fprintf(stderr, "%s: no widget with name \"%s\" found.\n",
  911.         ProgramName, options.top_object);
  912.     exit(1);
  913.     }
  914.  
  915.     XtAppAddActions (app_con, viewres_actions, XtNumber (viewres_actions));
  916.     XtOverrideTranslations
  917.     (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
  918.  
  919.     /*
  920.      * create dummy widgets to initialize resources
  921.      */
  922.     XtSetArg (args[0], XtNwidth, 1);
  923.     XtSetArg (args[1], XtNheight, 1);
  924.     dummy = XtCreateWidget ("dummy", widgetClass, toplevel, args, TWO);
  925.     for (i = 0; i < nwidgets; i++) {
  926.     XmuWidgetNode *node = &widget_list[i];
  927.     XmuWnFetchResources (node, dummy, topnode);
  928.     node->data = (XtPointer) create_viewres_data (node);
  929.     }
  930.     XtDestroyWidget (dummy);
  931.  
  932.     pane = XtCreateManagedWidget ("pane", panedWidgetClass, toplevel,
  933.                   (ArgList) NULL, ZERO);
  934.  
  935.     box = XtCreateManagedWidget ("buttonbox", boxWidgetClass, pane,
  936.                  (ArgList) NULL, ZERO);
  937.     quitButton = XtCreateManagedWidget ("quit", commandWidgetClass, box,
  938.                     (ArgList) NULL, ZERO);
  939.  
  940.     /*
  941.      * Format menu
  942.      */
  943.     XtSetArg (args[0], XtNmenuName, "viewMenu");
  944.     viewButton = XtCreateManagedWidget ("view", menuButtonWidgetClass, box,
  945.                     args, ONE);
  946.     viewMenu = XtCreatePopupShell ("viewMenu", simpleMenuWidgetClass, 
  947.                    viewButton, (ArgList) NULL, ZERO);
  948.     XtSetArg (args[0], XtNcallback, callback_rec);
  949.  
  950. #define MAKE_VIEW(n,v,name) \
  951.     callback_rec[0].closure = (XtPointer) v; \
  952.     view_widgets[n] = XtCreateManagedWidget (name, smeBSBObjectClass, \
  953.                          viewMenu, args, ONE)
  954.     callback_rec[0].callback = (XtCallbackProc) gravity_callback;
  955.     MAKE_VIEW (VIEW_HORIZONTAL, WestGravity, "layoutHorizontal");
  956.     MAKE_VIEW (VIEW_VERTICAL, NorthGravity, "layoutVertical");
  957.  
  958.     (void) XtCreateManagedWidget ("line1", smeLineObjectClass, viewMenu,
  959.                   (ArgList) NULL, ZERO);
  960.  
  961.     callback_rec[0].callback = (XtCallbackProc) variable_labeltype_callback;
  962.     MAKE_VIEW (VIEW_VARIABLES, TRUE, "namesVariable");
  963.     MAKE_VIEW (VIEW_CLASSES, FALSE, "namesClass");
  964.  
  965.     (void) XtCreateManagedWidget ("line2", smeLineObjectClass, viewMenu,
  966.                   (ArgList) NULL, ZERO);
  967.  
  968.     callback_rec[0].callback = (XtCallbackProc) show_resources_callback;
  969.     MAKE_VIEW (VIEW_SHOW_RESOURCES, BOOL_ON, "viewResources");
  970.     MAKE_VIEW (VIEW_HIDE_RESOURCES, BOOL_OFF, "viewNoResources");
  971. #undef MAKE_VIEW
  972.  
  973.     /*
  974.      * Select menu
  975.      */
  976.     XtSetArg (args[0], XtNmenuName, "selectMenu");
  977.     selectButton = XtCreateManagedWidget ("select", menuButtonWidgetClass, box,
  978.                       args, ONE);
  979.     selectMenu = XtCreatePopupShell ("selectMenu", simpleMenuWidgetClass, 
  980.                      selectButton, (ArgList) NULL, ZERO);
  981.     XtSetArg (args[0], XtNcallback, callback_rec);
  982.     callback_rec[0].callback = (XtCallbackProc) select_callback;
  983. #define MAKE_SELECT(n,name) \
  984.     callback_rec[0].closure = (XtPointer) n; \
  985.     select_widgets[n] = XtCreateManagedWidget (name, smeBSBObjectClass, \
  986.                            selectMenu, args, ONE)
  987.     MAKE_SELECT (SELECT_NOTHING, "unselect");
  988.     MAKE_SELECT (SELECT_ALL, "selectAll");
  989.     MAKE_SELECT (SELECT_INVERT, "selectInvert");
  990.     (void) XtCreateManagedWidget ("line1", smeLineObjectClass, selectMenu,
  991.                   (ArgList) NULL, ZERO);
  992.     MAKE_SELECT (SELECT_PARENT, "selectParent");
  993.     MAKE_SELECT (SELECT_ANCESTORS, "selectAncestors");
  994.     MAKE_SELECT (SELECT_CHILDREN, "selectChildren");
  995.     MAKE_SELECT (SELECT_DESCENDANTS, "selectDescendants");
  996.     (void) XtCreateManagedWidget ("line2", smeLineObjectClass, selectMenu,
  997.                   (ArgList) NULL, ZERO);
  998.     MAKE_SELECT (SELECT_HAS_RESOURCES, "selectHasResources");
  999.     MAKE_SELECT (SELECT_SHOWN_RESOURCES, "selectShownResources");
  1000. #undef MAKE_SELECT
  1001.  
  1002.     form = XtCreateManagedWidget ("treeform", formWidgetClass, pane,
  1003.                   (ArgList) NULL, ZERO);
  1004.     /*
  1005.      * create the panner and the porthole and then connect them with the
  1006.      * callbacks (passing the other widget each callback)
  1007.      */
  1008.     XtSetArg (args[0], XtNbackgroundPixmap, None);  /* faster updates */
  1009.     porthole = XtCreateManagedWidget ("porthole", portholeWidgetClass, form,
  1010.                       args, ONE);
  1011.     panner = XtCreateManagedWidget ("panner", pannerWidgetClass, form,
  1012.                     (ArgList) NULL, ZERO);
  1013.  
  1014.     XtSetArg (args[0], XtNreportCallback, callback_rec);
  1015.     callback_rec[0].callback = (XtCallbackProc) panner_callback;
  1016.     callback_rec[0].closure = (XtPointer) porthole;
  1017.     XtSetValues (panner, args, ONE);
  1018.  
  1019.     callback_rec[0].callback = (XtCallbackProc) porthole_callback;
  1020.     callback_rec[0].closure = (XtPointer) panner;
  1021.     XtSetValues (porthole, args, ONE);
  1022.  
  1023.     /*
  1024.      * now that the panner and porthole are set up, insert the tree and 
  1025.      * fix up the menu, fill in the nodes
  1026.      */
  1027.     treeWidget = XtCreateManagedWidget ("tree", treeWidgetClass,
  1028.                     porthole, (ArgList) NULL, ZERO);
  1029.  
  1030.     set_labeltype_menu (options.show_variable, FALSE);
  1031.     XtSetArg (args[0], XtNgravity, &grav);
  1032.     XtGetValues (treeWidget, args, ONE);
  1033.     set_orientation_menu (grav, FALSE);
  1034.     update_selection_items ();
  1035.     build_tree (topnode, treeWidget, (Widget) NULL);
  1036.  
  1037.     /*
  1038.      * Realize the tree, but do not map it (we set mappedWhenManaged to 
  1039.      * false up above).  Get the initial size of the tree so that we can
  1040.      * size the panner appropriately.
  1041.      */
  1042.     XtRealizeWidget (toplevel);
  1043.  
  1044.     wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
  1045.                    False);
  1046.     (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
  1047.                             &wm_delete_window, 1);
  1048.  
  1049.     XtSetArg (args[0], XtNwidth, &canvasWidth);
  1050.     XtSetArg (args[1], XtNheight, &canvasHeight);
  1051.     XtGetValues (treeWidget, args, TWO);
  1052.  
  1053.     XtSetArg (args[0], XtNwidth, &sliderWidth);
  1054.     XtSetArg (args[1], XtNheight, &sliderHeight);
  1055.     XtGetValues (porthole, args, TWO);
  1056.  
  1057.     XtSetArg (args[0], XtNcanvasWidth, canvasWidth);
  1058.     XtSetArg (args[1], XtNcanvasHeight, canvasHeight);
  1059.     XtSetArg (args[2], XtNsliderWidth, sliderWidth);
  1060.     XtSetArg (args[3], XtNsliderHeight, sliderHeight);
  1061.     XtSetValues (panner, args, FOUR);
  1062.  
  1063.     XRaiseWindow (XtDisplay(panner), XtWindow(panner));
  1064.     XtAppMainLoop (app_con);
  1065. }
  1066.  
  1067.  
  1068.  
  1069. /*****************************************************************************
  1070.  *                                                                           *
  1071.  *           viewres translation table action routines                 *
  1072.  *                                                                           *
  1073.  *****************************************************************************/
  1074.  
  1075. /* ARGSUSED */
  1076. static void ActionQuit (w, event, params, num_params)
  1077.     Widget w;
  1078.     XEvent *event;
  1079.     String *params;
  1080.     Cardinal *num_params;
  1081. {
  1082.     exit (0);
  1083. }
  1084.  
  1085. /* ARGSUSED */
  1086. static void ActionSetLableType (w, event, params, num_params)
  1087.     Widget w;
  1088.     XEvent *event;
  1089.     String *params;
  1090.     Cardinal *num_params;
  1091. {
  1092.     char *cmd;
  1093.     Boolean oldvar = options.show_variable, newvar;
  1094.  
  1095.     switch (*num_params) {
  1096.       case 0:
  1097.     cmd = "toggle";
  1098.     break;
  1099.       case 1:
  1100.     cmd = params[0];
  1101.     break;
  1102.       default:
  1103.     XBell (XtDisplay(w), 0);
  1104.     return;
  1105.     }
  1106.  
  1107.     if (XmuCompareISOLatin1 (cmd, "toggle") == 0) {
  1108.     newvar = !oldvar;
  1109.     } else if (XmuCompareISOLatin1 (cmd, "variable") == 0) {
  1110.     newvar = TRUE;
  1111.     } else if (XmuCompareISOLatin1 (cmd, "class") == 0) {
  1112.     newvar = FALSE;
  1113.     } else {
  1114.     XBell (XtDisplay(w), 0);
  1115.     return;
  1116.     }
  1117.  
  1118.     if (newvar != oldvar) set_labeltype_menu (newvar, TRUE);
  1119.     return;
  1120. }
  1121.  
  1122. /* ARGSUSED */
  1123. static void ActionSetOrientation (w, event, params, num_params)
  1124.     Widget w;
  1125.     XEvent *event;
  1126.     String *params;
  1127.     Cardinal *num_params;
  1128. {
  1129.     XtGravity newgrav = ForgetGravity;
  1130.  
  1131.     if (*num_params < 1) {
  1132.     Arg arg;
  1133.     XtGravity oldgrav = ForgetGravity;
  1134.  
  1135.     XtSetArg (arg, XtNgravity, &oldgrav);
  1136.     XtGetValues (treeWidget, &arg, ONE);
  1137.     switch (oldgrav) {
  1138.       case WestGravity:  newgrav = NorthGravity; break;
  1139.       case NorthGravity:  newgrav = WestGravity; break;
  1140.       case EastGravity:  newgrav = SouthGravity; break;
  1141.       case SouthGravity:  newgrav = EastGravity; break;
  1142.       default:
  1143.         return;
  1144.     }
  1145.     } else {
  1146.     XrmValue fromval, toval;
  1147.  
  1148.     fromval.size = sizeof (String);
  1149.     fromval.addr = (XPointer) params[0];
  1150.     toval.size = sizeof (XtGravity);
  1151.     toval.addr = (XPointer) &newgrav;
  1152.     XtConvertAndStore (treeWidget, XtRString, &fromval,
  1153.                XtRGravity, &toval);
  1154.     }
  1155.  
  1156.     switch (newgrav) {
  1157.       case WestGravity: case NorthGravity: case EastGravity: case SouthGravity:
  1158.     break;
  1159.       default:
  1160.     XBell (XtDisplay(w), 0);
  1161.     return;
  1162.     }
  1163.  
  1164.     set_orientation_menu (newgrav, TRUE);
  1165.     return;
  1166. }
  1167.  
  1168.  
  1169. static void do_single_arg (w, params, nparams, table, nentries, proc)
  1170.     Widget w;
  1171.     String *params;
  1172.     Cardinal nparams;
  1173.     struct _nametable table[];
  1174.     int nentries;
  1175.     void (*proc)();
  1176. {
  1177.     int obj;
  1178.     int i;
  1179.  
  1180.     if (nparams != 1) {
  1181.     XBell (XtDisplay(w), 0);
  1182.     return;
  1183.     }
  1184.  
  1185.     for (i = 0; i < nentries; i++) {
  1186.     if (XmuCompareISOLatin1 (params[0], table[i].name) == 0) {
  1187.         obj = table[i].value;
  1188.         break;
  1189.     }
  1190.     }
  1191.     if (i == nentries) {
  1192.     XBell (XtDisplay(w), 0);
  1193.     return;
  1194.     }
  1195.  
  1196.     /*
  1197.      * use any old widget
  1198.      */
  1199.     (*proc) (w, (XtPointer) obj, (XtPointer) NULL);
  1200. }
  1201.  
  1202.  
  1203. /* ARGSUSED */
  1204. static void ActionSelect (w, event, params, num_params)
  1205.     Widget w;
  1206.     XEvent *event;
  1207.     String *params;
  1208.     Cardinal *num_params;
  1209. {
  1210.     do_single_arg (w, params, *num_params, select_nametable, 
  1211.            (int) XtNumber(select_nametable), select_callback);
  1212. }
  1213.  
  1214.  
  1215. /* ARGSUSED */
  1216. static void ActionResources (w, event, params, num_params)
  1217.     Widget w;
  1218.     XEvent *event;
  1219.     String *params;
  1220.     Cardinal *num_params;
  1221. {
  1222.     if (*num_params == 0) {
  1223.     show_resources_callback (w, (XtPointer) BOOL_TOGGLE, (XtPointer) NULL);
  1224.     } else {
  1225.     do_single_arg (w, params, *num_params, boolean_nametable,
  1226.                (int) XtNumber(boolean_nametable),
  1227.                show_resources_callback);
  1228.     }
  1229. }
  1230.  
  1231.